#include <iostream>
#include <math.h>
using namespace std;

#define PI 3.14159265
#define G 9.80665					// in meters

//values are in meters unless otherwise specified
const float cfInitVelocity = 30;	 // initial velocity of the penguin (m/s)
const float cfMass = 10;             // mass of the penguin in kilograms
const float cfDownSlope = 20;
const float cfHorizSlope = 2;
const float cfUpwardSlope = 2;
const float cfTimeIncrement = .01;
const float cfUpwardAngle = 60;      // in degrees
const float cfDownwardAngle = 60;    // in degrees
const float cfHeightAboveWater = 5;


float degToRad(float);
float QuadEquation(float, float, float);
void Update(float, float&, float&, float&);

int main()
{
	float fTime = 0;
	float fPosition = 0;
	float fVelocity;
	float fAccel;
	//calculate initial velocity in the specified direction
	fVelocity = cfInitVelocity * cos(degToRad(cfDownwardAngle));
	//calculate acceleration for the first part of the ramp
	fAccel = G * cos(degToRad(90 - cfDownwardAngle));

	cout << "My starting velocity is: " << fVelocity << endl;
	cout << "My starting acceleration is: " << fAccel << endl;

	//run through simulation of the penguin sliding down the first slope
	while(fPosition <= cfDownSlope)
	{
		Update(fAccel, fVelocity, fPosition, fTime);
	}

	cout << "\nI've gone down the ramp.\n";
	cout << "Now ending velocity is: " << fVelocity << endl;
	cout << "So far it's been: " << fTime << " seconds\n";

	//calculate velocity at new (horizontal) angle
	fVelocity = fVelocity * cos(degToRad(cfDownwardAngle));
	//since the penguin is now going horizontally, there is no acceleration
	fAccel = 0;

	cout << "\nSliding onto the horizontal part now. Acceleration is zero\n";
	cout << "My new velocity is: " << fVelocity << endl;

	//run through simulation of penguin sliding straight across the bottom of the ramp
	while(fPosition <= (cfDownSlope + cfHorizSlope))
	{
		Update(fAccel, fVelocity, fPosition, fTime);
	}

	cout << "\nAbout to go up the ramp next\n";
	cout << "Velocity is: " << fVelocity << " should be the same as a second ago.\n";
	cout << "So far it's been: " << fTime << " seconds\n";

	//calculate velocity now that there is new angle
	fVelocity = fVelocity * cos(degToRad(cfUpwardAngle));
	fAccel = -G * cos(degToRad(90 - cfUpwardAngle));

	cout << "\nGoing up the ramp\n";
	cout << "New velocity is: " << fVelocity << endl;
	cout << "Now my acceleration is: " << fAccel << endl;

	//run through simulation of the penguin going up the last part of the ramp
	while(fPosition <= (cfDownSlope + cfHorizSlope + cfUpwardSlope))
	{
		Update(fAccel, fVelocity, fPosition, fTime);
	}

	cout << "Projectile time\n";

	return 0;
}

//a simple conversion to degrees to radians
float degToRad(float deg)
{
	return ((deg * PI) / 180);
}

//used to compute theoretical aspects
float quadEquation(float A, float B, float C)
{
	float ans1, ans2;

	//calculates both possible answers
	ans1 = ((B * -1) + sqrt((B * B) - (4 * A * C))) / ( 2 * A);
	ans2 = ((B * -1) - sqrt((B * B) - (4 * A * C))) / ( 2 * A);

	//returns the positive answer
	if(ans1 >= 0)
		return ans1;

	return ans2;
}

void Update(float a, float &v, float &p, float &t)
{
	//update velocity
	v += a * cfTimeIncrement;
	//update position
	p += v * cfTimeIncrement;

	//update total time
	t += cfTimeIncrement;
}

